
import { v2, Vec2 } from 'cc';
import GameInputMgr from '../input/GameInputMgr';
import { InputType } from '../input/InputConfig';
// import InputConverter from '../input/InputConverter';

export const ACTION_SET = ["GameControl"];
export const DIGITALS = ["A", "Y", "X", "B", "LB", "RB", "LT", "RT", "Menu", "Up", "Left", "Right", "Down"];
export const ANALOGS = ["Move", "Look"];
//steam键值 根据DIGITALS 的顺序得来
export enum SteamKeyCode {
    A,          // A
    Y,        // Y
    X,        // X
    B,    // B
    LB,    // LB
    RB,   // RB
    LT,  // LT
    RT,  // RT
    Menu,     // Menu
    Up,      // 上
    Left,   // 左
    Down,   // 下
    Right,   // 右
}
// /**
//  * 摇杆对应的值
//  */
// let STEAM_ROCKER_CODE = {

// }

const VEC_RIGHT = v2(1, 0);
const vectorBuff = v2();

let DIR_LIST: SteamKeyCode[] = [SteamKeyCode.Up, SteamKeyCode.Down, SteamKeyCode.Left, SteamKeyCode.Right]
//八个方向对应的的steam的键值
let KEY_LIST: SteamKeyCode[][] = [
    [SteamKeyCode.Right, SteamKeyCode.Up],
    [SteamKeyCode.Up],
    [SteamKeyCode.Left, SteamKeyCode.Up],
    [SteamKeyCode.Left],
    [SteamKeyCode.Left, SteamKeyCode.Down],
    [SteamKeyCode.Down],
    [SteamKeyCode.Down, SteamKeyCode.Right],
    [SteamKeyCode.Right],
]

let KEY_CODE = {
    A: SteamKeyCode.A,
    Y: SteamKeyCode.Y,
    X: SteamKeyCode.X,
    B: SteamKeyCode.B,
    LB: SteamKeyCode.LB,
    RB: SteamKeyCode.RB,
    LT: SteamKeyCode.LT,
    RT: SteamKeyCode.RT,
    Menu: SteamKeyCode.Menu,
    Up: SteamKeyCode.Up,
    Left: SteamKeyCode.Left,
    Down: SteamKeyCode.Down,
    Right: SteamKeyCode.Right,
    ROCKER_LEFT: 0,
    ROCKER_RIGHT: 3,
}
//https://partner.steamgames.com/doc/api/isteaminput
export default class SteamInputMgr {
    private static ins: SteamInputMgr
    static getInstance() {
        if (!this.ins) {
            this.ins = new SteamInputMgr();
        }
        return this.ins;
    }
    protected platName: string = InputType.STEAM;
    private _gameCtrl: steam.SteamManager = null;
    //存储摇杆触发的键值
    private joyStickPressState: boolean[] = []

    //左右方向的摇杆是否将摇杆数值改为方向键值。
    private changeDirAnalog: boolean[] = [false, false]
    setChangeDirAnlog(index: number, flag: boolean) {
        this.changeDirAnalog[index] = flag;
    }

    start() {
        if (this.isActive()) {
            if (!this._gameCtrl) {
                this._gameCtrl = steam.SteamManager.getInstance();
                this._gameCtrl!.init(ACTION_SET, DIGITALS, ANALOGS);
                this._gameCtrl!.activeActionSet(ACTION_SET[0]);
                console.warn(' steam init ok ')
                GameInputMgr.getInstance().converter.addKeyCode(this.platName, KEY_CODE)
            }
        } else {
            console.warn(' steam is error init ')
        }
    }

    isActive() {
        return window['steam'] != undefined;
    }

    /**
     * 更新按键的状态
     * @param digital 
     * @param _joyStickPress 
     * @param _joyStickRelease 
     */
    private updateState(digital: number[], _joyStickPress: number[], _joyStickRelease: number[]) {
        for (let i = 0; i < digital.length; i += 2) {
            let keyCode = digital[i];
            // let keyValue = this.getKeyValue(keyCode)
            if (digital[i + 1]) {
                if (!this.joyStickPressState[i]) {
                    this.joyStickPressState[i] = true;
                    _joyStickPress.push(keyCode)
                }
            } else {
                if (this.joyStickPressState[i]) {
                    this.joyStickPressState[i] = false;
                    _joyStickRelease.push(keyCode)
                }
            }
        }
    }

    update(deltaTime: number) {
        if (this._gameCtrl) {
            this._gameCtrl!.update();
            let _joyStickPress: number[] = [];
            let _joyStickRelease: number[] = [];
            let digital = this._gameCtrl!.getDigitalChangeData();
            let analog = this._gameCtrl!.getAnalogChangeData();
            this.updateState(digital, _joyStickPress, _joyStickRelease)
            if (analog.length > 0) {
                GameInputMgr.getInstance().changeType(this.platName)
                for (let i = 0; i < analog.length; i += 3) {
                    let keyIndex = analog[i];
                    if (this.changeDirAnalog[i]) {
                        vectorBuff.set(analog[i + 1], analog[i + 2]);
                        //手指离开 已经使用摇杆
                        let tempAnalogPress: number[] = this.getDirKeyCode(vectorBuff)
                        this.updateState(tempAnalogPress, _joyStickPress, _joyStickRelease)
                    } else {
                        GameInputMgr.getInstance().onRockerEvent(this.platName, keyIndex, analog[i + 1], analog[i + 2])
                    }


                }

            }

            if (_joyStickPress.length > 0) {
                GameInputMgr.getInstance().changeType(this.platName)
                for (let index = 0; index < _joyStickPress.length; index++) {
                    GameInputMgr.getInstance().onKeyBoardPress(this.platName, _joyStickPress[index], null)
                }
            }

            if (_joyStickRelease.length > 0) {
                for (let index = 0; index < _joyStickRelease.length; index++) {
                    GameInputMgr.getInstance().onKeyBoardRelease(this.platName, _joyStickRelease[index], null)
                }
            }
        }
    }

    /**
     * 键值是否包含指定按键
    */
    public isContainKeys(_keyCode: number, keys: number): boolean {
        return (_keyCode & keys) == keys;
    }


    /**
     * 通过给定的向量，获得向量对应的方向键的键值
     * @param vectorBuff 
     * @returns 
     */
    private getDirKeyCode(vectorBuff: Vec2): number[] {
        let state: number[] = []
        for (let index = 0; index < DIR_LIST.length; index++) {
            const keyCode = DIR_LIST[index];
            state[index * 2] = keyCode;
            state[index * 2 + 1] = 0;
        }
        if (vectorBuff.length() > 0.5) {
            let angle = vectorBuff.angle(VEC_RIGHT) * 180 / Math.PI;
            if (vectorBuff.y < 0)
                angle = 360 - angle;
            // console.log('getDirKeyCode  angle ', angle, vectorBuff.x, vectorBuff.y)
            let section = 0;
            if (angle < 22.5)
                section = 7;
            else
                section = Math.floor((angle - 22.5) / 45);

            console.log('getDirKeyCode  section ', section)
            let keyList = KEY_LIST[section]
            if (keyList) {
                for (let index = 0; index < keyList.length; index++) {
                    const keyCode = keyList[index];
                    for (let j = 0; j < state.length; j += 2) {
                        if (state[j] == keyCode) {
                            state[j + 1] = 1
                            break;
                        }
                    }
                }
                console.log('getDirKeyCode  state ', state)
            }

        }
        return state;
    }
}

